import 'package:xbaistack/widget/icon_list.dart';
import 'package:xbaistack/widget/my_button.dart';
import 'package:flutter/material.dart';

/// 视图状态
enum Status {
  LOADING, // 加载中
  LOADED, // 加载完成后的一个状态
  EMPTY, // 加载成功，但是没有数据
  TIMEOUT, // 网络请求超时
  FAILED, // 加载失败
  NETWORK_ERROR, // 网络异常
}

/// 状态视图加载器
class StatusView extends StatefulWidget {
  final Duration? delayForTest;
  final String? message;
  final Status status; // 初始化状态，用于显示一个初始化视图
  final VoidCallback? retry; // 重试回调，当需要重试的时候会调用此函数
  final WidgetBuilder? builder; // 视图构造器，用于渲染加载完成后的真正视图
  final StatusViewController? controller; // 加入视图控制器

  StatusView({
    this.status = Status.LOADING,
    this.builder,
    this.retry,
    this.controller,
    this.delayForTest, this.message,
  }) : super(key: controller?._key); // 这里引用 Controller 中定义的 GlobalKey

  @override
  State<StatefulWidget> createState() => _StatusViewState();
}

/// State for [StatusView] widget
class _StatusViewState extends State<StatusView> {
  late Status _status; // 记录当前的状态

  @override
  void initState() {
    super.initState();
    _delayTesting();
    _status = widget.status; // // 使用 StatusView 中的状态进行初始化
  }

  void _delayTesting() {
    if (widget.delayForTest != null) {
      WidgetsBinding.instance.addPostFrameCallback((_){
          print(31);
          Future.delayed(
            widget.delayForTest!,
            () => _changeStatus(Status.LOADED),
          );
        },
      );
    }
  }

  @override
  void didUpdateWidget(covariant StatusView oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.status != widget.status) {
      _status = widget.status;
    }
  }

  // build 中我们只需要根据不同的枚举状态返回不同状态的视图即可
  // 仅当状态为 LOADED 时，我们直接调用外部的 WidgetBuilder 以返回真正需要渲染的视图
  @override
  Widget build(BuildContext context) {
    return switch (_status) {
      Status.TIMEOUT => _timeoutView(),
      Status.LOADING => _loadingView(),
      Status.EMPTY => _emptyView(),
      Status.FAILED => _failedView(),
      Status.NETWORK_ERROR => _networkErrorView(),
      Status.LOADED => widget.builder?.call(context) ?? const Text("Loaded"),
    };
  }

  /// 切换视图状态
  void _changeStatus(Status status) {
    if (_status != status) {
      // 这里是为了避免同一种状态下重复刷新，节省资源
      setState(() => _status = status); // 调用 setState 刷新页面
    }
  }

  /// 因为所有的状态视图几乎都是同一种布局
  /// 所以这里我们可以定义一个基础的布局方式，然后不同的视图传入不同的子项即可
  Widget _baseView(List<Widget> items) {
    return CustomScrollView(
      physics: const BouncingScrollPhysics(
        parent: AlwaysScrollableScrollPhysics(), // 具有回弹效果
      ),
      slivers: [
        SliverFillRemaining(
          // 尽可能的撑满剩余空间
          hasScrollBody: false,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            mainAxisAlignment: MainAxisAlignment.center,
            children: items,
          ),
        ),
      ],
    );
  }

  /// LOADING 对应的加载中视图
  /// CircularProgressIndicator 是 Flutter 自带的一个显示加载进度的组件
  Widget _loadingView() {
    return _baseView([
      const SizedBox(
        height: 22,
        width: 22,
        child: CircularProgressIndicator(color: Colors.blueAccent),
      ),
      const Padding(
        padding: EdgeInsets.all(10),
        child: Text("加载中，请稍候", style: TextStyle(color: Colors.grey)),
      ),
    ]);
  }

  /// TIMEOUT 对应的超时视图
  Widget _timeoutView() {
    return _baseView([
      const Icon(IconFonts.TIMEOUT, size: 48, color: Colors.grey),
      const Padding(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 20),
        child: Text("请求超时，请重新加载试一试", style: TextStyle(color: Colors.grey)),
      ),
      _retryButton(),
    ]);
  }

  /// NETWOR_ERROR 对应的网络异常视图
  Widget _networkErrorView() {
    return _baseView([
      const Icon(IconFonts.NET_ERROR, size: 48, color: Colors.grey),
      const Padding(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 20),
        child: Text("网络异常，请确保您的网络正常", style: TextStyle(color: Colors.grey)),
      ),
      _retryButton(),
    ]);
  }

  /// EMPTY 对应的空视图
  Widget _emptyView() {
    return _baseView([
      const Icon(IconFonts.EMPTY, size: 48, color: Colors.grey),
      const Padding(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 20),
        child: Text("暂无更多数据，请重新加载试一试", style: TextStyle(color: Colors.grey)),
      ),
      _retryButton(),
    ]);
  }

  /// FAILED 对应的加载失败视图
  Widget _failedView() {
    return _baseView([
      const Icon(IconFonts.DATA_ERROR, size: 48, color: Colors.grey),
      const Padding(
        padding: EdgeInsets.fromLTRB(10, 10, 10, 20),
        child: Text("加载失败，请重新加载试一试", style: TextStyle(color: Colors.grey)),
      ),
      _retryButton(),
    ]);
  }

  /// 重试按钮，通过这个按钮我们可以将其点击事件绑定到外部的重试回调函数上
  Widget _retryButton() {
    return MyButtons(
      text: "重新加载",
      icon: const Icon(Icons.refresh, size: 16),
      style: const TextStyle(fontSize: 12),
      onTap: widget.retry, // 绑定重试回调函数
      padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
    );
  }
}

/// 状态视图控制器
class StatusViewController {
  final GlobalKey<_StatusViewState> _key = GlobalKey();

  bool get isReady => _key.currentState != null && _key.currentState!.mounted;
  _StatusViewState? get _state => isReady ? _key.currentState : null;

  void showLoading() => _state?._changeStatus(Status.LOADING);
  void showFailed() => _state?._changeStatus(Status.FAILED);
  void showEmpty() => _state?._changeStatus(Status.EMPTY);
  void showNetworkError() => _state?._changeStatus(Status.NETWORK_ERROR);
  void showTimeout() => _state?._changeStatus(Status.TIMEOUT);
  void loaded() => _state?._changeStatus(Status.LOADED);
}
